home *** CD-ROM | disk | FTP | other *** search
- /*
- * mdbexp.c - MINIX expresion parser
- *
- * Written by Bruce D. Szablak
- *
- * This free software is provided for non-commerical use. No warrantee
- * of fitness for any use is implied. You get what you pay for. Anyone
- * may make modifications and distribute them, but please keep this header
- * in the distribution. NOTE: A PORTION OF THIS FILE IS DERIVED FROM THE
- * SOURCE TO ANM.C WHOSE AUTHOR IS UNKNOWN TO ME (AST?). BEWARE THAT
- * OTHER RESTRICTIONS MAY APPLY.
- */
-
- #include <ctype.h>
- #include <setjmp.h>
- #include <stdio.h>
- #include "user.h"
- #include "out.h"
-
- extern jmp_buf mainlp;
- extern curpid;
-
- int nsyms;
- struct outname *nbufp = NULL;
- long value(), strtol(), lookup(), ptrace();
-
- #define idchar(c) (isalpha(c) || isdigit(c) || (c) == '_')
-
- char *
- addr_to_name(rel_addr, off_p)
- long rel_addr, *off_p;
- {
- register int i, l = 0, r = nsyms;
-
- while (l < r)
- {
- i = (l + r) >> 1;
- if (rel_addr < nbufp[i].on_valu) r = i;
- else if (rel_addr > nbufp[i].on_valu) l = i + 1;
- else break;
- }
- if (l == nsyms || r == 0)
- {
- *off_p = rel_addr;
- return "_start";
- }
- if (rel_addr < nbufp[i].on_valu) i--;
- *off_p = rel_addr - nbufp[i].on_valu;
- return nbufp[i].on_mptr;
- }
-
- symbolic(addr, sep)
- long addr;
- char sep;
- {
- long off;
- extern long saddr, eaddr;
-
- if (addr < saddr || addr > eaddr)
- {
- printf("0x%lx%c", addr, sep);
- return;
- }
- fputs(addr_to_name(addr - saddr, &off), stdout);
- if (off) printf("+0x%lx", off);
- fputc(sep, stdout);
- }
-
- char *
- getexp(buf, exp_p, seg_p)
- char *buf;
- int *seg_p;
- long *exp_p;
- {
- extern char *skip();
- long v = 0L;
-
- buf = skip(buf);
- if ((isalpha(*buf) && (isspace(buf[1]) || buf[1]==';'))
- || *buf=='\n' || *buf==';' || *buf=='/' || *buf == '!')
- {
- *exp_p = 0L;
- return buf;
- }
- v = value(buf, &buf, seg_p);
- buf = skip(buf);
- if (*buf == '+')
- {
- v += value(skip(buf+1), &buf, seg_p);
- }
- else if (*buf == '-')
- {
- v -= value(skip(buf+1), &buf, seg_p);
- }
- *exp_p = v;
- return skip(buf);
- }
-
- long
- reg_addr(s)
- char *s;
- {
- long val;
-
- switch (*s++)
- {
- case 'a': case 'A': val = 32; break;
- case 'd': case 'D': val = 0; break;
- default: goto error;
- }
- if (*s >= '0' && *s <= '7')
- {
- return val + 4*(*s - '0');
- }
-
- error:
- printf("Unknown register: %2.2s\n", s);
- /* longjmp(mainlp); --jrb */
- longjmp(mainlp, 1); /* ++jrb */
- }
-
- long
- value(s, s_p, seg_p)
- char *s, **s_p;
- int *seg_p;
- {
- long k;
-
- if (*s == '\'') /* handle character constants here */
- {
- *s_p = s + 2;
- return s[1];
- }
- if (*s == '-' || isdigit(*s))
- {
- return strtol(s, s_p, 0);
- }
- if (*s == '$')
- {
- k = reg_addr(s+1);
- *s_p = s + 3;
- return ptrace(3, curpid, k, 0L);
- }
- return lookup(s, s_p, seg_p);
- }
-
- long
- lookup(s, s_p, seg_p)
- char *s, **s_p;
- int *seg_p;
- {
- extern long saddr;
- char c;
- int i, l;
-
- for (l = 1; idchar(s[l]); ++l ) {}
- c = s[l]; s[l] = 0;
-
- if (strcmp("_start", s) == 0)
- {
- *seg_p = T;
- *(*s_p = s + 6) = c;
- return saddr;
- }
- for (i = 0; i < nsyms; i++)
- if (strcmp(nbufp[i].on_mptr, s) == 0)
- {
- *seg_p = (nbufp[i].on_type & S_TYP) == S_MIN ? T : D;
- *(*s_p = s + l) = c;
- return nbufp[i].on_valu + saddr;
- }
-
- printf("%s: symbol not found\n", s);
- /* longjmp(mainlp); -- jrb */
- longjmp(mainlp, 1); /* ++jrb */
- }
-
- /******************END OF ORIGINAL CODE***********************/
-
- /*
- * The following code is actually a highly edited
- * version of anm.c - The ACK version of nm
- * That file's header follows:
- */
-
- /* @(#)anm.c 1.6 */
- /*
- ** print symbol tables for
- ** ACK object files
- **
- ** anm [-gopruns] [name ...]
- */
-
- #define ushort unsigned short
-
- long off;
- #ifdef __STDC__
- void *malloc(unsigned);
- void *realloc(void *, unsigned);
- #else
- char *malloc();
- char *realloc();
- #endif
- long s_base[S_MAX]; /* for specially encoded bases */
-
- getsyms(file)
- char *file;
- {
- int compare();
- FILE *fi;
- struct outsect sbuf;
- struct outhead hbuf;
- struct outname nbuf;
- char *cbufp;
- long fi_to_co;
- long n;
- unsigned readcount;
- int j;
-
- fi = fopen(file,"r");
- if (fi == NULL) {
- fprintf(stderr, "db: cannot open %s\n", file);
- return;
- }
-
- getofmt((char *)&hbuf, SF_HEAD, fi);
- if (BADMAGIC(hbuf)) {
- fprintf(stderr, "db: %s-- bad format\n", file);
- fclose(fi);
- return;
- }
-
- n = hbuf.oh_nname;
- if (n == 0) {
- fprintf(stderr, "db: %s-- no name list\n", file);
- fclose(fi);
- return;
- }
-
- if (hbuf.oh_nchar == 0) {
- fprintf(stderr, "db: %s-- no names\n", file);
- fclose(fi);
- return;
- }
- if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) {
- fprintf(stderr, "db: string area too big in %s\n", file);
- exit(2);
- }
-
- /* store special section bases */
- if (hbuf.oh_flags & HF_8086) {
- int i;
- for (i=0; i<hbuf.oh_nsect; i++) {
- getofmt((char *)&sbuf, SF_SECT, fi);
- s_base[i+S_MIN] =
- (sbuf.os_base>>12) & 03777760;
- }
- }
-
- if ((cbufp = (char *)malloc(readcount)) == NULL) {
- fprintf(stderr, "db: out of memory on %s\n", file);
- exit(2);
- }
- fseek(fi, OFF_CHAR(hbuf), 0);
- if (fread(cbufp, 1, readcount, fi) == 0) {
- fprintf(stderr, "db: read error on %s\n", file);
- exit(2);
- }
- fi_to_co = (long)cbufp - OFF_CHAR(hbuf);
-
- fseek(fi, OFF_NAME(hbuf), 0);
- nsyms = 0;
- while (--n >= 0) {
- getofmt((char *)&nbuf, SF_NAME, fi);
-
- if (nbuf.on_foff == 0)
- continue; /* skip entries without names */
-
- if ((nbuf.on_type&S_EXT)==0)
- continue;
-
- nbuf.on_mptr = (char *)(nbuf.on_foff + fi_to_co);
-
- /* adjust value for specially encoded bases */
- if (hbuf.oh_flags & HF_8086) {
- if (((nbuf.on_type&S_ETC) == 0) ||
- ((nbuf.on_type&S_ETC) == S_SCT)) {
- j = nbuf.on_type&S_TYP;
- if ((j>=S_MIN) && (j<=S_MAX))
- nbuf.on_valu += s_base[j];
- }
- }
-
- if (nbufp == NULL)
- nbufp = (struct outname *)malloc(sizeof(struct outname));
- else
- nbufp = (struct outname *)realloc(nbufp, (nsyms+1)*sizeof(struct outname));
- if (nbufp == NULL) {
- fprintf(stderr, "db: out of memory on %s\n", file);
- exit(2);
- }
- nbufp[nsyms++] = nbuf;
- }
-
- qsort(nbufp, nsyms, sizeof(struct outname), compare);
-
- fclose(fi);
- }
-
- compare(p1, p2)
- struct outname *p1, *p2;
- {
- if (p1->on_valu < p2->on_valu) return -1;
- if (p1->on_valu > p2->on_valu) return 1;
- return 0;
- }
-
- getofmt(p, s, f)
- register char *p;
- register char *s;
- register FILE *f;
- {
- register i;
- register long l;
-
- for (;;) {
- switch (*s++) {
- /* case '0': p++; continue; */
- case '1':
- *p++ = getc(f);
- continue;
- case '2':
- i = getc(f);
- i |= (getc(f) << 8);
- *((short *)p) = i; p += sizeof(short);
- continue;
- case '4':
- l = (long)getc(f);
- l |= ((long)getc(f) << 8);
- l |= ((long)getc(f) << 16);
- l |= ((long)getc(f) << 24);
- *((long *)p) = l; p += sizeof(long);
- continue;
- default:
- case '\0':
- break;
- }
- break;
- }
- }
-